package com.cgwx.testservice.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cgwx.commonutils.result.Result;
import com.cgwx.springsecurity.annotation.Log;
import com.cgwx.springsecurity.enums.BusinessType;
import com.cgwx.testservice.entity.Userfile;
import com.cgwx.testservice.entity.vo.UserFileQueryVo;
import com.cgwx.testservice.service.UserfileService;
import com.cgwx.testservice.utils.FileIconUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.util.UriUtils;

import java.io.*;
import java.nio.charset.StandardCharsets;

/**
 * <p>
 * 用户文件 前端控制器
 * </p>
 *
 * @author GaoWei
 * @since 2023-11-08
 */

@Api(tags = "用户文件前端控制器")
@RestController
@RequestMapping("/test/userfile")
@CrossOrigin
public class UserfileController {

    @Autowired
    private UserfileService userfileService;
    @Autowired
    private FileIconUtils fileIconUtils;

    @PreAuthorize("hasAuthority('bnt.userFile.upload')")
    @ApiOperation("上传用户文件")
    @PostMapping("uploadFile")
    public Result uploadFile(
            @ApiParam(name = "uploadFile", value = "待上传的用户文件")
            @RequestParam MultipartFile uploadFile,
            @ApiParam(name = "fileDescription", value = "上传的用户文件描述")
            @RequestParam String fileDescription,
            @ApiParam(name = "uploadUser", value = "上传的用户名称")
            @RequestParam String uploadUser) {
//        判断上传文件是否为空
        if(uploadFile.getOriginalFilename() != null)
        {
//            获取上传文件的原始文件名称
            String uploadFileName = uploadFile.getOriginalFilename();
//            获取上传文件的扩展名
            String uploadFileExtensionName = uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1);
//            根据扩展名获取文件图标
            String fileIconCode = fileIconUtils.setFileIconCode(uploadFileExtensionName);
//            创建Userfile类
            Userfile userfile = new Userfile();
//            设置Userfile类参数
            userfile.setFileName(uploadFileName);
            userfile.setFileType(uploadFileExtensionName);
            userfile.setFileIcon(fileIconCode);
            userfile.setFileDescribe(fileDescription);
            userfile.setUploadUser(uploadUser);
//            根据用户文件名称查询文件是否存在
            QueryWrapper<Userfile> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("file_name",uploadFileName);
            int count = userfileService.count(queryWrapper);
            if(count != 0 ){
//                存在同名文件，执行更新操作
                userfileService.update(userfile,queryWrapper);
            }else{
//                不存在同名文件，执行插入操作
                userfileService.save(userfile);
            }
//            设置文件路径及文件类
            String userFilePath = "userfile/";
            File dest = new File(new File(userFilePath).getAbsolutePath() + "/" + uploadFileName);
//            存储文件，同名文件会删除原文件
            try {
                uploadFile.transferTo(dest);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return Result.ok().data("message", "用户文件上传成功");
        }else {
            return Result.error().data("message", "用户文件上传失败");
        }
    }

    @Log(title = "删除用户文件", businessType = BusinessType.TEST_FILE_DELETE)
    @PreAuthorize("hasAuthority('bnt.userFile.remove')")
    @ApiOperation("删除用户文件")
    @DeleteMapping("removeUserFile/{id}")
    public Result removeUserFile(
            @ApiParam(name = "id", value = "待删除的用户文件id")
            @PathVariable Long id) {
        Userfile userfile = userfileService.getById(id);
//        从存储中删除文件
        String userFilePath = "userfile/";
        File dest = new File(new File(userFilePath).getAbsolutePath() + "/" + userfile.getFileName());
        boolean delete = dest.delete();
//        删除数据库信息
        boolean isSuccess = userfileService.removeById(id);
        if(delete && isSuccess) {
            return Result.ok().data("message", "用户文件删除成功");
        } else {
            return Result.error().data("message", "用户文件删除失败");
        }
    }

    @Log(title = "修改用户文件描述", businessType = BusinessType.TEST_FILE_UPDATE)
    @PreAuthorize("hasAuthority('bnt.userFile.update')")
    @ApiOperation("修改用户文件描述")
    @PostMapping("updateUserFile")
    public Result updateUserFile(
            @ApiParam(name = "userfile", value = "修改的用户文件类")
            @RequestBody Userfile userfile) {
//        执行更新操作
        boolean isSuccess = userfileService.updateById(userfile);
        if(isSuccess) {
            return Result.ok().data("message", "用户文件描述更新成功");
        } else {
            return Result.error().data("message", "用户文件描述更新失败");
        }
    }

    @ApiOperation("根据ID查询用户文件描述")
    @GetMapping("getUserFileDescribeById/{id}")
    public Result getUserFileDescribeById(
            @ApiParam(name = "id", value = "待修改的用户文件id")
            @PathVariable Long id) {
        Userfile userfile = userfileService.getById(id);
        return Result.ok().data("userfile",userfile);
    }

    @ApiOperation("条件分页查询用户文件列表")
    @GetMapping("{page}/{limit}")
    public Result queryUserFileList(
            @ApiParam(name = "page", value = "当前页")
            @PathVariable Long page,
            @ApiParam(name = "limit", value = "每页显示的记录数")
            @PathVariable Long limit,
            @ApiParam(name = "userFileQueryVo", value = "待查询的用户文件条件Vo")
                    UserFileQueryVo userFileQueryVo) {
        //创建page对象
        Page<Userfile> pageParam = new Page<>(page,limit);
        //调用service方法
        IPage<Userfile> pageModel = userfileService.selectPage(pageParam,userFileQueryVo);
        return Result.ok().data("pageModel",pageModel);
    }

    @PreAuthorize("hasAuthority('bnt.userFile.download')")
    @ApiOperation("下载用户文件")
    @PostMapping("downloadUserFile/{id}")
    public ResponseEntity<byte[]> downloadUserFile(
            @ApiParam(name = "id", value = "待下载的用户文件id")
            @PathVariable Long id) throws IOException {
//        查询要下载的用户文件对象
        Userfile userfile = userfileService.getById(id);
//        创建下载文件
        String userFilePath = "userfile/";
        File file = new File(new File(userFilePath).getAbsolutePath() + File.separator + userfile.getFileName());
//        设置请求状态码200
        ResponseEntity.BodyBuilder builder = ResponseEntity.ok();
//        内容长度
        builder.contentLength(file.length());
//        application/octet-stream 二进制数据流（最常见的文件下载）
        builder.contentType(MediaType.APPLICATION_OCTET_STREAM);
//        使用URLEncoding.decode对文件名进行解码
//        String downloadFileName = URLEncoder.encode(userfile.getFileName(), StandardCharsets.UTF_8);
//        解决下载文件名称空格变为“+”的问题
        String downloadFileName = UriUtils.encode(userfile.getFileName(), StandardCharsets.UTF_8);
//        根据浏览器类型，决定处理方式
        builder.header("Content-Disposition", "attachment; filename=" + downloadFileName);
        return builder.body(FileUtils.readFileToByteArray(file));
    }
}

